package com.lebang.service.cences;

import com.lebang.domain.CencesBusMember;
import com.lebang.domain.CencesNewusersCityscale;
import com.lebang.example.CencesBusMemberExample;
import com.lebang.mapper.ActiveMemberMapper;
import com.lebang.mapper.CencesBusMemberMapper;
import com.lebang.mapper.CencesNewusersCityscaleMapper;
import com.lebang.mapper.LbbMemberMapper;
import com.lebang.model.cences.CencesMsg;
import com.lebang.service.BaseService;
import com.lebang.service.mongodb.CencesMsgMongodb;
import com.lebangweb.common.TextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author ljx
 * @Date 2020-11-24
 */
@Service
public class CencesBusMemberService extends BaseService<CencesBusMember, Integer, CencesBusMemberExample> {
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    @Autowired
    private ActiveMemberMapper activeMemberMapper;
    @Autowired
    private CencesNewusersCityscaleMapper cencesNewusersCityscaleMapper;
    @Autowired
    private CencesBusMemberMapper mapper;
    @Autowired
    private CencesMsgMongodb cencesMsgMongodb;

    public void starDataInit(LocalDateTime end) {
        this.starDataInit(end, null);
    }

    /**
     * 指定日期公交用户统计
     *
     * @param end
     * @param brand
     */
    public void starDataInit(LocalDateTime end, List<String> brand) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDateTime star = end.minusDays(1);

        //统计日期
        int time = Integer.parseInt(end.toLocalDate().minusDays(1).format(df));

        if (brand == null) {
            //所有渠道
            brand = lbbMemberMapper.selectBrand();
        }
        List<String> city = lbbMemberMapper.selectCity();
        List<String> activeCity=activeMemberMapper.selectCity();
        List<String> allCity = Stream.of(city, activeCity)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());

        //每日活跃用户数
        List<CencesBusMember> activeMemberList = activeMemberMapper.countByTime(star, end);
        Map<String, List<CencesBusMember>> activeMemberMap = activeMemberList.stream().collect(Collectors.groupingBy(CencesBusMember::getAppStore));
        Map<String, List<CencesBusMember>> cityActiveMemberMap = activeMemberList.stream().filter(s -> s.getCity()!=null).collect(Collectors.groupingBy(CencesBusMember::getCity));


        //每日新增用户
        List<CencesBusMember> memberList = lbbMemberMapper.countByTime(star, end);
        Map<String, List<CencesBusMember>> memberMap = memberList.stream().collect(Collectors.groupingBy(CencesBusMember::getAppStore));
        Map<String, List<CencesBusMember>> cityMemberMap = memberList.stream().filter(s -> s.getCity()!=null).collect(Collectors.groupingBy(CencesBusMember::getCity));


        AtomicInteger activeCount = new AtomicInteger(0);
        AtomicInteger memberCount = new AtomicInteger(0);
        AtomicInteger cityMemberCount = new AtomicInteger(0);
        AtomicInteger cityActiveUserCount = new AtomicInteger(0);


        activeMemberList.forEach(s -> {
            s.setAppStore(s.getAppStore() + ":" + s.getCity());
        });
        Map<String, List<CencesBusMember>> activeScale = activeMemberList.stream().collect(Collectors.groupingBy(CencesBusMember::getAppStore));

        memberList.forEach(s -> {
            s.setAppStore(s.getAppStore() + ":" + s.getCity());
        });
        Map<String, List<CencesBusMember>> memberScale = memberList.stream().collect(Collectors.groupingBy(CencesBusMember::getAppStore));


        //分渠道
        for (String s : brand) {
            CencesBusMember busMember = new CencesBusMember();
            busMember.setCreateTime(star.toLocalDate());
            busMember.setTime(time);
            busMember.setNewUserCount(this.countNewUser(memberMap, s));
            busMember.setActiveUserCount(this.countActiveUser(activeMemberMap, s));
            busMember.setAppStore(s);
            mapper.insertSelective(busMember);

            memberCount.addAndGet(busMember.getNewUserCount());
            activeCount.addAndGet(busMember.getActiveUserCount());
            for (String c : city) {
                BigDecimal cityUserCount = new BigDecimal(this.countCityNewUser(memberScale, s, c));
                BigDecimal CityActiveCount = new BigDecimal(this.countCityActiveUser(activeScale, s, c));

                CencesNewusersCityscale cityscale = new CencesNewusersCityscale();
                cityscale.setCreateTime(star.toLocalDate());
                cityscale.setTime(time);
                cityscale.setCity(c);
                cityscale.setAppStore(s);
                cityscale.setNewUsersCount(cityUserCount.intValue());
                if (busMember.getNewUserCount() == 0) {
                    cityscale.setNewUserScale(0f);
                } else {
                    cityscale.setNewUserScale(cityUserCount.divide(new BigDecimal(busMember.getNewUserCount()), 2, BigDecimal.ROUND_HALF_UP).floatValue());
                }
                cityscale.setActiveUserCount(CityActiveCount.intValue());
                if (busMember.getActiveUserCount() == 0) {
                    cityscale.setActiveUserScale(0f);
                } else {
                    cityscale.setActiveUserScale(CityActiveCount.divide(new BigDecimal(busMember.getActiveUserCount()), 2, BigDecimal.ROUND_HALF_UP).floatValue());
                }

                cencesNewusersCityscaleMapper.insert(cityscale);
                cityMemberCount.addAndGet(cityscale.getNewUsersCount());
                cityActiveUserCount.addAndGet(cityscale.getActiveUserCount());
            }
        }
        //公交用户统计所有渠道
        CencesBusMember allBusMember = new CencesBusMember(star.toLocalDate(), time, memberCount.get(), activeCount.get(), "all");
        mapper.insertSelective(allBusMember);

        //公交用户城市比例所有渠道
        for (String c : allCity) {
            BigDecimal countCityActive = new BigDecimal(this.countCityActive(cityActiveMemberMap, c));
            BigDecimal countCityMember = new BigDecimal(this.countCityUser(cityMemberMap, c));
            CencesNewusersCityscale cityscale = new CencesNewusersCityscale();
            cityscale.setCreateTime(star.toLocalDate());
            cityscale.setTime(time);
            cityscale.setCity(c);
            cityscale.setAppStore("all");
            cityscale.setNewUsersCount(countCityMember.intValue());
            if (memberCount.get() == 0) {
                cityscale.setNewUserScale(0.0F);
            } else {
                cityscale.setNewUserScale(countCityMember.divide(new BigDecimal(memberCount.get()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).floatValue());
            }
            cityscale.setActiveUserCount(countCityActive.intValue());
            if (activeCount.get() == 0) {
                cityscale.setActiveUserScale(0.0F);
            } else {
                cityscale.setActiveUserScale(countCityActive.divide(new BigDecimal(activeCount.get()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).floatValue());
            }

            cencesNewusersCityscaleMapper.insert(cityscale);
        }
    }

    private Integer countActiveUser(Map<String, List<CencesBusMember>> map, String appStore) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(appStore);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getActiveUserCount());
        });
        return finish.get();
    }

    private Integer countNewUser(Map<String, List<CencesBusMember>> map, String appStore) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(appStore);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getNewUserCount());
        });
        return finish.get();
    }

    private Integer countCityNewUser(Map<String, List<CencesBusMember>> map, String appStore, String city) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(appStore + ":" + city);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getNewUserCount());
        });
        return finish.get();
    }

    private Integer countCityActiveUser(Map<String, List<CencesBusMember>> map, String appStore, String city) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(appStore + ":" + city);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getActiveUserCount());
        });
        return finish.get();
    }

    private Integer countCityActive(Map<String, List<CencesBusMember>> map, String city) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(city);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getActiveUserCount());
        });
        return finish.get();
    }

    private Integer countCityUser(Map<String, List<CencesBusMember>> map, String city) {
        AtomicInteger finish = new AtomicInteger(0);
        List<CencesBusMember> cencesBusMembers = map.get(city);
        if (cencesBusMembers == null) {
            return finish.get();
        }
        cencesBusMembers.forEach(s -> {
            finish.addAndGet(s.getNewUserCount());
        });
        return finish.get();
    }

    /**
     * 删除记录
     * @param time
     * @return
     */
    public int deleteRecord(Integer time) {
        CencesBusMemberExample example=new CencesBusMemberExample();
        example.createCriteria().andTimeEqualTo(time);
        return mapper.deleteByExample(example);
    }
}
